#include "AudioWrapperOpenAL.h"

const float AudioWrapperOpenAL::MIN_PITCH = 0.0f;
const float AudioWrapperOpenAL::MAX_PITCH = 2.0f;
const float AudioWrapperOpenAL::MIN_GAIN = 0.0f;
const float AudioWrapperOpenAL::MAX_GAIN = 1.0f;
const float AudioWrapperOpenAL::MIN_PAN = -1.0f;
const float AudioWrapperOpenAL::MAX_PAN = 1.0f;

AudioWrapperOpenAL::AudioWrapperOpenAL() {}

bool AudioWrapperOpenAL::initialize() {
	return alutInit(0,0);
}

bool AudioWrapperOpenAL::load(char* const iFilename) {
	mBufferHandle = alutCreateBufferFromFile(iFilename);
	if (mBufferHandle != AL_NONE) {
		alGenSources(1, &mSourceHandle);
		alSourcei(mSourceHandle, AL_BUFFER, mBufferHandle);
		alSourcei(mSourceHandle, AL_SOURCE_RELATIVE, AL_TRUE);
		alSource3f(mSourceHandle, AL_POSITION, 0.0f, -1.0f, 0.0f);
		setVolume(0.5f);
	}
	return mBufferHandle != AL_NONE;
}

void AudioWrapperOpenAL::unload() {
	alutExit();
}

void AudioWrapperOpenAL::play() {
	alSourcePlay(mSourceHandle);
}

void AudioWrapperOpenAL::pause() {
	alSourcePause(mSourceHandle);
}

void AudioWrapperOpenAL::playPause() {
	ALint isPlaying;
	alGetSourcei(mSourceHandle, AL_SOURCE_STATE, &isPlaying);
	if (isPlaying == AL_PLAYING) {
		pause();
	} else {
		play();
	}
}

void AudioWrapperOpenAL::stop() {
	alSourceStop(mSourceHandle);
}

void AudioWrapperOpenAL::exit() {
	alutExit();
}

bool AudioWrapperOpenAL::isLooping() {
	ALint isLooping;
	alGetSourcei(mSourceHandle, AL_LOOPING, &isLooping);;
	return isLooping == AL_TRUE;
}

void AudioWrapperOpenAL::setLooping(bool iIsLooping) {
	if (iIsLooping) {
		alSourcei(mSourceHandle, AL_LOOPING, 1);
	} else {
		alSourcei(mSourceHandle, AL_LOOPING, 0);
	}
}

void AudioWrapperOpenAL::toggleLooping() {
	setLooping(!isLooping());
}

ALfloat AudioWrapperOpenAL::getVolume() const {
	ALfloat gain;
	alGetSourcef(mSourceHandle, AL_GAIN, &gain);
	return gain;
}

void AudioWrapperOpenAL::setVolume(ALfloat iVal) {
	clampFloat( iVal, MIN_GAIN, MAX_GAIN );
	alSourcef(mSourceHandle, AL_GAIN, iVal);
}

ALfloat AudioWrapperOpenAL::getPan() const {
	ALfloat position[3];
	alGetSource3f(mSourceHandle, AL_POSITION, &position[0], &position[1], &position[2]);
	return position[0];
}

void AudioWrapperOpenAL::setPan(ALfloat iVal) {
	clampFloat( iVal, MIN_PAN, MAX_PAN );
	ALfloat position[3];
	alGetSource3f(mSourceHandle, AL_POSITION, &position[0], &position[1], &position[2]);
	alSource3f(mSourceHandle, AL_POSITION, iVal, -1.0f, 0.0f);
}

ALfloat AudioWrapperOpenAL::getPitch() const {
	ALfloat pitch;
	alGetSourcef(mSourceHandle, AL_PITCH, &pitch);
	return pitch;
}

void AudioWrapperOpenAL::setPitch(ALfloat iVal) {
	clampFloat( iVal, MIN_PITCH, MAX_PITCH );
	alSourcef(mSourceHandle, AL_PITCH, iVal);
}

void AudioWrapperOpenAL::clampFloat(float &iValue, float iMin, float iMax) {
	if (iValue < iMin)
		iValue = iMin;
	if (iValue > iMax)
		iValue = iMax;
}
